/**
 * 
 */
package fr.mynounou.web.beans;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.bean.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;

import org.apache.log4j.Logger;
import org.primefaces.event.FlowEvent;
import org.primefaces.model.DashboardColumn;
import org.primefaces.model.DashboardModel;
import org.primefaces.model.DefaultDashboardColumn;
import org.primefaces.model.DefaultDashboardModel;

import fr.mynounou.entities.Enfant;
import fr.mynounou.entities.Parent;
import fr.mynounou.entities.Utilisateur;
import fr.mynounou.entities.contrats.Bebe;
import fr.mynounou.entities.contrats.Contrat;
import fr.mynounou.entities.contrats.Periscolaire;
import fr.mynounou.exceptions.dao.ExistingEntityException;
import fr.mynounou.web.model.dao.ContratDao;
import fr.mynounou.web.model.dao.EnfantDao;
import fr.mynounou.web.model.dao.UserDao;

/**
 * @author btavernier
 * 
 */
@SuppressWarnings("serial")
@ManagedBean(name = "ContratController")
@SessionScoped
public class ContratController implements Serializable {

	@ManagedProperty(value = "#{ConnectionController}")
	private ConnectionController connCtrl;

	@ManagedProperty(value = "#{ContratDAO}")
	private ContratDao contratDao;

	@ManagedProperty(value = "#{UserDAO}")
	private UserDao userDao;

	@ManagedProperty(value = "#{EnfantDAO}")
	private EnfantDao enfantDao;

	private Parent[] selectedParents;
	private List<Parent> parents = null;

	Enfant enfant = new Enfant();
	Date maxDate = new Date();
	Parent p1 = new Parent();
	Parent p2 = new Parent();
	boolean skipP2 = false, createUserP1 = true, createUserP2 = true;
	int typeContrat;
	double tarif;
	
	private DashboardModel model;
	
	public ContratController(){
		model = new DefaultDashboardModel();
		DashboardColumn column1 = new DefaultDashboardColumn();
		DashboardColumn column2 = new DefaultDashboardColumn();
		DashboardColumn column3 = new DefaultDashboardColumn();
		

		column1.addWidget("enfants");
		column2.addWidget("parents");
		column3.addWidget("contrats");

		model.addColumn(column1);
		model.addColumn(column2);
		model.addColumn(column3);
	}

	Logger logger = Logger.getLogger(getClass());

	public String onFlowProcess(FlowEvent event) {
		logger.info("Current wizard step:" + event.getOldStep());
		logger.info("Next step:" + event.getNewStep());

		if (event.getOldStep().equals("parent1")) {

			if (selectedParents == null) {
				return event.getOldStep();
			}
			logger.info(selectedParents.length);
			if (selectedParents.length >= 1 && selectedParents.length <= 2) {
				return event.getNewStep();
			} else {
				return event.getOldStep();
			}
		}

		return event.getNewStep();
	}

	public void save(ActionEvent actionEvent) {
		Contrat c;

		p1.setLogin(p1.getEmail());
		p1.setPassword(p1.getEmail());

		if (typeContrat == 1) {
			Bebe b = new Bebe();
			c = b;
		} else if (typeContrat == 2) {
			Periscolaire p = new Periscolaire();
			c = p;
		} else {
			Logger.getLogger(getClass()).error(
					"[CONTRAT] Type de contrat invalide : " + typeContrat);
			return;
		}

		c.setEnfant(enfant);
		c.setNounou(connCtrl.getNounou());
		c.setTarif(tarif);
		ArrayList<Parent> parents = new ArrayList<>();
		parents.add(p1);
		if (!createUserP2) {
			ArrayList<Enfant> listE = new ArrayList<>(p2.getEnfants());
			listE.add(enfant);
			p2.setLogin(p2.getEmail());
			p2.setPassword(p2.getEmail());
			p2.setEnfants(listE);
			parents.add(p2);
		}
		c.setParents(parents);

		enfant.setContrat(c);

		ArrayList<Enfant> listE = new ArrayList<>(p1.getEnfants());
		listE.add(enfant);
		p1.setEnfants(listE);

		try {
			enfantDao.saveEnfant(enfant);
		} catch (ExistingEntityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			userDao.saveUser(p1);

		} catch (ExistingEntityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		try {
			if (!createUserP2) {
				userDao.saveUser(p2);
			}
		} catch (ExistingEntityException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		contratDao.createContrat(c);

		FacesMessage msg = new FacesMessage("Successful", "Welcome :"
				+ p1.getNom());
		FacesContext.getCurrentInstance().addMessage(null, msg);
	}

	/**
	 * @return the enfant
	 */
	public Enfant getEnfant() {
		return enfant;
	}

	/**
	 * @param enfant
	 *            the enfant to set
	 */
	public void setEnfant(Enfant enfant) {
		this.enfant = enfant;
	}

	/**
	 * @return the maxDate
	 */
	public Date getMaxDate() {
		return maxDate;
	}

	/**
	 * @param maxDate
	 *            the maxDate to set
	 */
	public void setMaxDate(Date maxDate) {
		this.maxDate = maxDate;
	}

	/**
	 * @return the p1
	 */
	public Parent getP1() {
		return p1;
	}

	/**
	 * @param p1
	 *            the p1 to set
	 */
	public void setP1(Parent p1) {
		this.p1 = p1;
	}

	/**
	 * @return the p2
	 */
	public Parent getP2() {
		return p2;
	}

	/**
	 * @param p2
	 *            the p2 to set
	 */
	public void setP2(Parent p2) {
		this.p2 = p2;
	}

	/**
	 * @return the skipP2
	 */
	public boolean getSkipP2() {
		return skipP2;
	}

	/**
	 * @param skipP2
	 *            the skipP2 to set
	 */
	public void setSkipP2(boolean skipP2) {
		this.skipP2 = skipP2;
	}

	/**
	 * @return the createUser
	 */
	public boolean getCreateUserP1() {
		return createUserP1;
	}

	/**
	 * @param createUser
	 *            the createUser to set
	 */
	public void setCreateUserP1(boolean createUser) {
		this.createUserP1 = createUser;
	}

	/**
	 * @return the createUser
	 */
	public boolean getCreateUserP2() {
		return createUserP2;
	}

	/**
	 * @param createUser
	 *            the createUser to set
	 */
	public void setCreateUserP2(boolean createUser) {
		this.createUserP2 = createUser;
	}

	/**
	 * @return the connCtrl
	 */
	public ConnectionController getConnCtrl() {
		return connCtrl;
	}

	/**
	 * @param connCtrl
	 *            the connCtrl to set
	 */
	public void setConnCtrl(ConnectionController connCtrl) {
		this.connCtrl = connCtrl;
	}

	/**
	 * @return the typeContrat
	 */
	public int getTypeContrat() {
		return typeContrat;
	}

	/**
	 * @param typeContrat
	 *            the typeContrat to set
	 */
	public void setTypeContrat(int typeContrat) {
		this.typeContrat = typeContrat;
	}

	/**
	 * @return the tarif
	 */
	public double getTarif() {
		return tarif;
	}

	/**
	 * @param tarif
	 *            the tarif to set
	 */
	public void setTarif(double tarif) {
		this.tarif = tarif;
	}

	/**
	 * @return the contratDao
	 */
	public ContratDao getContratDao() {
		return contratDao;
	}

	/**
	 * @param contratDao
	 *            the contratDao to set
	 */
	public void setContratDao(ContratDao contratDao) {
		this.contratDao = contratDao;
	}

	/**
	 * @return the userDao
	 */
	public UserDao getUserDao() {
		return userDao;
	}

	/**
	 * @param userDao
	 *            the userDao to set
	 */
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	/**
	 * @return the enfantDao
	 */
	public EnfantDao getEnfantDao() {
		return enfantDao;
	}

	/**
	 * @param enfantDao
	 *            the enfantDao to set
	 */
	public void setEnfantDao(EnfantDao enfantDao) {
		this.enfantDao = enfantDao;
	}

	// public ParentsDataModel getParents() {
	// if (parents == null) {
	// parents = new ParentsDataModel(userDao.listParents(connCtrl
	// .getNounou()));
	// }
	// return parents;
	// }

	public List<Parent> getParents() {
		if (parents == null) {
			parents = userDao.listParents(connCtrl.getNounou());
		}
		return parents;
	}

	/**
	 * @return the selectedParent1
	 */
	public Parent[] getSelectedParents() {
		return selectedParents;
	}

	/**
	 * @param selectedParent1
	 *            the selectedParent1 to set
	 */
	public void setSelectedParents(Parent[] selectedParents) {
		this.selectedParents = selectedParents;
	}

	/**
	 * @return the model
	 */
	public DashboardModel getModel() {
		return model;
	}

	/**
	 * @param model the model to set
	 */
	public void setModel(DashboardModel model) {
		this.model = model;
	}
}
